package imp

import (
	sqlc "bgs/db/sqlc"
	activityGrpc "bgs/grpc/gen/service/activity"
	"bgs/grpc/gen/shared/message"
	activityService "bgs/service/activity"
	"bgs/service/model"
	"bgs/util"
	"context"
)

/****************************************************************************************/
/*                               activity entity of helper                              */
/****************************************************************************************/

func transformActivityOfU2CWithStatAndOwnerInfoEntityToPb(
	warehouses []*message.Warehouse,
	productAttributeDefs model.AttributeDefMapOfProduct,
	activityProductWithProductInfos []sqlc.ListNormalActivityProductWithProductInfosByActivityIDRow,
	activitySkuWithProductOrProductSpecInfos []*model.ActivitySkuWithProductOrProductSpecInfo,
) func(sqlc.GetActivityOfU2CWithStatAndOwnerInfoForUserRow) *activityGrpc.ActivityOfU2CWithStatAndOwnerInfoEntity {
	return func(o sqlc.GetActivityOfU2CWithStatAndOwnerInfoForUserRow) *activityGrpc.ActivityOfU2CWithStatAndOwnerInfoEntity {
		return &activityGrpc.ActivityOfU2CWithStatAndOwnerInfoEntity{
			Id:                                     o.ID,
			BrandId:                                o.BrandID,
			PubUserId:                              o.PubUserID,
			StoreId:                                o.StoreID.Int64,
			DistributorId:                          o.DistributorID.Int64,
			Name:                                   o.Name,
			Type:                                   o.Type,
			Intro:                                  string(o.Intro),
			ProcessStatus:                          o.ProcessStatus,
			Published:                              sqlc.GoNTimeToPBTimestamp(o.Published),
			Begined:                                sqlc.GoTimeToPBTimestamp(o.Begined),
			Ended:                                  sqlc.GoTimeToPBTimestamp(o.Ended),
			TimeRanges:                             transformTimeRangeEntityToPb(o.TimeRanges),
			Background:                             o.Background.String,
			Poster:                                 o.Poster.String,
			SaleMode:                               o.SaleMode,
			VerifyQualification:                    o.VerifyQualification,
			QualifyTypes:                           o.QualifyTypes,
			DeliveryModes:                          o.DeliveryModes,
			IsUseWarehouseShippingFeeRule:          o.IsUseWarehouseShippingFeeRule,
			UnifiedShippingFee:                     o.UnifiedShippingFee.Int32,
			SpokesmanId:                            o.SpokesmanID.Int64,
			MinimumPurchaseAmount:                  o.MinimumPurchaseAmount,
			Tel:                                    o.Tel,
			Owner:                                  o.Owner,
			OwnerName:                              o.OwnerName,
			OwnerPic:                               o.OwnerPic,
			OrderCount:                             o.OrderCount,
			LatestAccessed:                         sqlc.GoTimeToPBTimestamp(o.LatestAccessed),
			Pv:                                     o.Pv,
			Uv:                                     o.Uv,
			Iv:                                     o.Iv,
			Warehouses:                             warehouses,
			ActivityProductWithAttributeDefAndSkus: mapActivityProductWithAttributeDefAndSkuToPb(activityProductWithProductInfos, productAttributeDefs, activitySkuWithProductOrProductSpecInfos, transActivityProductWithAttributeDefAndSkuToPb),
			IsWxpayAvailable:                       o.IsWxpayAvailable,
			// CanManage:                              o.CanManage,
			OpenEndorseToUser:             o.OpenEndorseToUser,
			HasNotEndorsed:                o.HasNotEndorsed,
			IsEndorsementEntranceDisplay:  o.IsEndorsementEntranceDisplay,
			EndorseSpokesmanId:            o.EndorseSpokesmanID,
			IsDistributionEntranceDisplay: o.IsDistributionEntranceDisplay,
			DistributeDistributorId:       o.DistributeDistributorID,
		}
	}
}

/****************************************************************************************/
/*                            activityJoins entity of query                             */
/****************************************************************************************/

// GetActivityOfU2CWithStatAndOwnerInfoForUser C端用户获取活动信息及统计、权限信息
func (s *ActivityAPIService) GetActivityOfU2CWithStatAndOwnerInfoForUser(ctx context.Context, req *activityGrpc.GetActivityOfU2CWithStatAndOwnerInfoForUserRequest) (res *activityGrpc.GetActivityOfU2CWithStatAndOwnerInfoForUserResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("activityImp->GetActivityOfU2CWithStatAndOwnerInfoForUser:%v", req)
	res = &activityGrpc.GetActivityOfU2CWithStatAndOwnerInfoForUserResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}

	q := s.dao.Q

	activityOfU2CWithStatAndOwnerInfo, err := q.GetActivityOfU2CWithStatAndOwnerInfoForUser(ctx, sqlc.GetActivityOfU2CWithStatAndOwnerInfoForUserParams{
		ID:     req.Id,
		UserID: req.UserId,
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}

	activityID := util.IfThenElse(activityOfU2CWithStatAndOwnerInfo.Owner == string(sqlc.EmActivityOwnerSpokesman), activityOfU2CWithStatAndOwnerInfo.ParentID.Int64, activityOfU2CWithStatAndOwnerInfo.ID).(int64)

	normalActivityWarehouses, err := q.ListNormalBrandActivityWarehousesByActivityID(ctx, activityID)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}

	warehouseIDs := util.MapToInt64(util.ToGenericSlice(normalActivityWarehouses), func(v interface{}) int64 {
		val := v.(sqlc.ActivityWarehouse)
		return val.WarehouseID
	})
	slog.Infof("warehouseIDs:=>%+v", warehouseIDs)
	var warehouses []*message.Warehouse
	cached := s.cacher.FetchWarehouses(warehouseIDs)
	for _, v := range cached {
		warehouses = append(warehouses, &message.Warehouse{
			Id:            v.WarehouseID,
			Tel:           v.Tel,
			Linkman:       v.Linkman,
			Address:       v.Address,
			Lng:           v.Lng,
			Lat:           v.Lat,
			CityCode:      v.CityCode,
			DeliveryModes: v.DeliveryModes,
		})
	}

	normalActivityProductWithProductInfos, normalActivitySkus, err := s.activityService.FetchNormalProductAndSkusWithRealtimeStock(ctx, q, &activityService.FetchProductOrSkusWithRealtimeStockParam{
		ActivityID: activityOfU2CWithStatAndOwnerInfo.ID,
		ParentID:   activityOfU2CWithStatAndOwnerInfo.ParentID.Int64,
		Owner:      sqlc.EmActivityOwner(activityOfU2CWithStatAndOwnerInfo.Owner),
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}

	productIDs := util.MapToInt64(util.ToGenericSlice(normalActivityProductWithProductInfos), func(v interface{}) int64 {
		val := v.(sqlc.ListNormalActivityProductWithProductInfosByActivityIDRow)
		return val.ProductID
	})

	mapOfProductAttributeDefs, err := s.productService.FetchMapOfProductAttributeDefs(ctx, q, productIDs)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.ActivityOfU2CWithStatAndOwnerInfo = transformActivityOfU2CWithStatAndOwnerInfoEntityToPb(warehouses, mapOfProductAttributeDefs, normalActivityProductWithProductInfos, normalActivitySkus)(activityOfU2CWithStatAndOwnerInfo)
	return
}
